package com.zy.explore.db.infrastructure.plugins.sqlprint;

import com.zy.explore.db.infrastructure.plugins.util.SqlPrintUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.sql.Connection;
import java.sql.Statement;
import java.util.Properties;

/**
 * 建类说明：sql拦截器
 *
 * @author 中国印
 * @date 2022年02月16日 21:34:31
 */
@Intercepts({
        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
        @Signature(type = StatementHandler.class, method = "getBoundSql", args = {}),
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
})
@Slf4j
public class SqlInterceptor implements Interceptor {

    // @Override
    // public Object intercept(Invocation invocation) throws Throwable {
    //     Object in = invocation.getArgs()[0];
    //     // 日志代理类(这个类为mybatis日志类)
    //     PreparedStatementLogger preparedStatementLogger = (PreparedStatementLogger) Proxy.getInvocationHandler(in);
    //     // 使用druid连接池，得到完整的sql (也可以使用反射执行PreparedStatementLogger中打印参数方法实现)
    //     String wholeSql = preparedStatementLogger.getPreparedStatement().toString().replaceAll("(\r\n|\n)", " ");
    //     log.info("完整的SQL执行语句为：{}", wholeSql);
    //     return invocation.proceed();
    // }
    //
    // @Override
    // public Object plugin(Object target) {
    //     return Plugin.wrap(target, this);
    // }
    //
    // @Override
    // public void setProperties(Properties properties) {
    //
    // }


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 打印sql和执行时间
        return SqlPrintUtil.printNonQuerySql(invocation);
    }


    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }

}
